import { Injectable, Logger } from '@nestjs/common';
import { FanqieCrawler } from '../crawler/fanqie.crawler';
import { ICrawler, NovelInfo } from '../crawler/interfaces/crawler.interface';

export interface AccessibilityResult {
  status: 'success' | 'failed';
  responseTime: number;
  finalUrl: string;
  httpStatus: number;
  error?: string;
}

export interface ContentParsingResult {
  status: 'success' | 'failed';
  novelInfo?: NovelInfo;
  error?: string;
}

export interface DataIntegrityResult {
  status: 'success' | 'warning' | 'failed';
  score: number;
  missingFields: string[];
  dataQuality: 'excellent' | 'good' | 'fair' | 'poor';
  recommendations?: string[];
}

export interface ShareLinkTestResults {
  accessibility: AccessibilityResult;
  contentParsing: ContentParsingResult;
  dataIntegrity: DataIntegrityResult;
}

export interface TestSummary {
  overallStatus: 'success' | 'partial_success' | 'failed';
  testTime: string;
  recommendations: string[];
}

@Injectable()
export class TestService {
  private readonly logger = new Logger(TestService.name);

  constructor(private fanqieCrawler: FanqieCrawler) {}

  /**
   * 测试分享链接的可访问性
   */
  async testLinkAccessibility(shareUrl: string): Promise<AccessibilityResult> {
    const startTime = Date.now();

    try {
      this.logger.log(`开始测试链接可访问性: ${shareUrl.substring(0, 100)}...`);

      // 尝试解析分享链接
      const finalUrl = await this.fanqieCrawler.parseShareUrl(shareUrl);
      const responseTime = Date.now() - startTime;

      // 验证最终URL是否有效
      const isValid = this.fanqieCrawler.validateUrl(finalUrl);

      if (isValid && finalUrl.includes('fanqienovel.com')) {
        return {
          status: 'success',
          responseTime,
          finalUrl,
          httpStatus: 200,
        };
      } else {
        return {
          status: 'failed',
          responseTime,
          finalUrl,
          httpStatus: 404,
          error: '无法获取有效的小说页面URL',
        };
      }
    } catch (error) {
      const responseTime = Date.now() - startTime;
      this.logger.error(`链接可访问性测试失败: ${error.message}`);

      return {
        status: 'failed',
        responseTime,
        finalUrl: shareUrl,
        httpStatus: 500,
        error: error.message,
      };
    }
  }

  /**
   * 测试内容解析能力
   */
  async testContentParsing(novelUrl: string): Promise<ContentParsingResult> {
    try {
      this.logger.log(`开始测试内容解析能力: ${novelUrl.substring(0, 100)}...`);

      const novelInfo = await this.fanqieCrawler.getNovelInfo(novelUrl);

      return {
        status: 'success',
        novelInfo,
      };
    } catch (error) {
      this.logger.error(`内容解析测试失败: ${error.message}`);

      return {
        status: 'failed',
        error: error.message,
      };
    }
  }

  /**
   * 验证数据完整性
   */
  async validateDataIntegrity(novelInfo: NovelInfo): Promise<DataIntegrityResult> {
    const missingFields: string[] = [];
    const recommendations: string[] = [];
    let score = 10;

    // 检查必填字段
    const requiredFields = ['title', 'author', 'description'];
    for (const field of requiredFields) {
      if (!novelInfo[field] || novelInfo[field].trim() === '') {
        missingFields.push(field);
        score -= 2;
      }
    }

    // 检查可选但重要的字段
    const importantFields = ['cover', 'category', 'chapterList'];
    for (const field of importantFields) {
      if (!novelInfo[field] || (Array.isArray(novelInfo[field]) && novelInfo[field].length === 0)) {
        missingFields.push(field);
        score -= 1;
      }
    }

    // 特殊检查章节列表
    if (novelInfo.chapterList && novelInfo.chapterList.length > 0) {
      if (novelInfo.chapterList.length < 10) {
        recommendations.push('章节数量较少，可能不完整');
        score -= 0.5;
      }
    } else {
      recommendations.push('缺少章节列表信息');
      score -= 2;
    }

    // 检查内容质量
    if (novelInfo.description && novelInfo.description.length < 50) {
      recommendations.push('小说简介过短，可能不完整');
      score -= 0.5;
    }

    // 确定数据质量等级
    let dataQuality: 'excellent' | 'good' | 'fair' | 'poor';
    if (score >= 9) dataQuality = 'excellent';
    else if (score >= 7) dataQuality = 'good';
    else if (score >= 5) dataQuality = 'fair';
    else dataQuality = 'poor';

    // 确定整体状态
    let status: 'success' | 'warning' | 'failed';
    if (score >= 8) status = 'success';
    else if (score >= 5) status = 'warning';
    else status = 'failed';

    return {
      status,
      score: Math.max(0, score),
      missingFields,
      dataQuality,
      recommendations,
    };
  }

  /**
   * 执行完整的分享链接测试流程
   */
  async testShareLink(shareUrl: string): Promise<{
    success: boolean;
    testResults: ShareLinkTestResults;
    summary: TestSummary;
  }> {
    this.logger.log(`开始执行完整测试流程: ${shareUrl.substring(0, 100)}...`);

    // 步骤1：测试链接可访问性
    const accessibilityResult = await this.testLinkAccessibility(shareUrl);

    let contentParsingResult: ContentParsingResult;
    let dataIntegrityResult: DataIntegrityResult;

    if (accessibilityResult.status === 'success') {
      // 步骤2：测试内容解析能力
      contentParsingResult = await this.testContentParsing(accessibilityResult.finalUrl);

      if (contentParsingResult.status === 'success' && contentParsingResult.novelInfo) {
        // 步骤3：验证数据完整性
        dataIntegrityResult = await this.validateDataIntegrity(contentParsingResult.novelInfo);
      } else {
        dataIntegrityResult = {
          status: 'failed',
          score: 0,
          missingFields: ['无法获取小说信息'],
          dataQuality: 'poor',
          recommendations: ['请检查链接是否有效或网络连接'],
        };
      }
    } else {
      contentParsingResult = {
        status: 'failed',
        error: '链接不可访问，跳过内容解析测试',
      };

      dataIntegrityResult = {
        status: 'failed',
        score: 0,
        missingFields: ['链接不可访问'],
        dataQuality: 'poor',
        recommendations: [accessibilityResult.error || '请检查分享链接是否有效'],
      };
    }

    // 生成测试总结
    const summary = this.generateTestSummary(
      accessibilityResult,
      contentParsingResult,
      dataIntegrityResult
    );

    const overallSuccess = summary.overallStatus !== 'failed';

    return {
      success: overallSuccess,
      testResults: {
        accessibility: accessibilityResult,
        contentParsing: contentParsingResult,
        dataIntegrity: dataIntegrityResult,
      },
      summary,
    };
  }

  /**
   * 生成测试总结
   */
  private generateTestSummary(
    accessibility: AccessibilityResult,
    contentParsing: ContentParsingResult,
    dataIntegrity: DataIntegrityResult
  ): TestSummary {
    const recommendations: string[] = [];

    // 收集所有推荐
    if (dataIntegrity.recommendations) {
      recommendations.push(...dataIntegrity.recommendations);
    }

    if (accessibility.error) {
      recommendations.push(`访问性问题: ${accessibility.error}`);
    }

    if (contentParsing.error) {
      recommendations.push(`解析问题: ${contentParsing.error}`);
    }

    // 确定整体状态
    let overallStatus: 'success' | 'partial_success' | 'failed';
    const successCount = [
      accessibility.status === 'success',
      contentParsing.status === 'success',
      dataIntegrity.status === 'success'
    ].filter(Boolean).length;

    if (successCount === 3) {
      overallStatus = 'success';
    } else if (successCount >= 1) {
      overallStatus = 'partial_success';
    } else {
      overallStatus = 'failed';
    }

    return {
      overallStatus,
      testTime: new Date().toISOString(),
      recommendations,
    };
  }
}